package me.zhengjie.log.aop;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.UUID;

@Aspect
@Slf4j
@RequiredArgsConstructor
public abstract class WebLogBase {

    public String getMethodName(Class<?> beanClass, Method method) {
        // 生成包含参数类型的唯一键（解决重载问题）
        StringBuilder keyBuilder = new StringBuilder();
        keyBuilder.append(beanClass.getName())  // 类名
                .append("#")
                .append(method.getName())      // 方法名
                .append("(");
        // 拼接参数类型（按顺序，用全类名）
        Class<?>[] parameterTypes = method.getParameterTypes();
        for (int i = 0; i < parameterTypes.length; i++) {
            if (i > 0) {
                keyBuilder.append(",");
            }
            keyBuilder.append(parameterTypes[i].getName());  // 参数类型的全类名
        }
        keyBuilder.append(")");
        return keyBuilder.toString();
    }

    public String getMethodUnionId(JoinPoint joinPoint) {
        // 1. 获取方法签名（强转为MethodSignature，因为切点是方法）
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        // 2. 获取目标方法（Method对象）
        Method method = methodSignature.getMethod();
        // 3. 获取目标方法所在的类（beanClass）
        // 方式一：通过方法签名获取声明该方法的类（可能是接口）
        // Class<?> targetBeanClass = methodSignature.getDeclaringType();
        // 方式二：通过joinPoint.getTarget()获取实际代理的目标对象的类（推荐，获取真实实现类）
        Class<?> beanClass = joinPoint.getTarget().getClass();
        return getMethodName(beanClass, method);
    }

    /**
     * 从请求头获取traceId（支持跨服务追踪）
     */
    public String getTraceIdFromHeader() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            String traceId = request.getHeader("X-Trace-Id");
            if (traceId == null) {
                traceId = UUID.randomUUID().toString().replace("-", "");
            }
            return traceId;
        }
        return null;
    }


}
